function Watcher(vm, exp, cb) {
    this.cb = cb;
    this.vm = vm;
    this.exp = exp;
    this.value = this.get();  // 将自己添加到订阅器的操作
}

Watcher.prototype = {
    update: function() {
        this.run();
    },
    run: function() {
        const value = Utils.getValueByExp(this.vm,this.exp);
        const oldVal = this.value;
        if (value !== oldVal) {
            this.value = value;
            this.cb.call(this.vm, value, oldVal);
        }
    },
    get: function() {
        Dep.target = this;  // 缓存自己

        // getValueByKeys 里面会经过多层get，这意味着每一次get都会把自己放入get到的value的监听者中
        // 这是合理的吗？
        // 如果不放入会怎么样
        // 是不是应该在想要的位置再放入自己?
        // 会有很多层的嵌套监听吗？
        // 如果父对象消失了，会发生什么？

        /**
         * 设置父节点时子节点也会更新
         * 原理：getValue时，一个watcher会将自己放到exp拆分出的数组对应的所有节点的订阅者数组中
         * 所以，此watcher会监听exp数组上的所有节点对象，从而做到父节点更新时也能做到更新
         * 
         */
        const value = Utils.getValueByExp(this.vm.data,this.exp);  // 强制执行监听器里的get函数
        Dep.target = null;  // 释放自己
        return value;
    }
};
//export default Watcher;
